#if UNITY_2023_1_OR_NEWER
using System;
using System.Collections;
using System.Collections.Generic;

#if UNITY_6000_0_OR_NEWER
using System.Diagnostics;
#endif

using Unity.Properties;
using UnityEngine;
using UnityEngine.Internal;
using UnityEngine.UIElements;

namespace LS.UI.Localization
{
    public class LOTab : Tab, ILocalizationReplay
    {
        [Serializable]
        [ExcludeFromDocs]
        public new class UxmlSerializedData : Tab.UxmlSerializedData
        {
            [SerializeField]
            [UxmlAttribute("localization-key")]
            private string m_LocalizationKey;

            [SerializeField]
            [UxmlAttribute("use-framework-localization")]
            private bool m_UseFrameworkLocalization;

#if UNITY_6000_0_OR_NEWER
            [HideInInspector]
            [UxmlIgnore]
            [SerializeField]
            private UxmlAttributeFlags m_LocalizationKey_UxmlAttributeFlags;

            [HideInInspector]
            [UxmlIgnore]
            [SerializeField]
            private UxmlAttributeFlags m_UseFrameworkLocalization_UxmlAttributeFlags;
#endif
            public override object CreateInstance()
            {
                return new LOTab();
            }

            public override void Deserialize(object obj)
            {
                base.Deserialize(obj);
                LOTab tab = (LOTab)obj;
#if UNITY_6000_0_OR_NEWER
                if (UnityEngine.UIElements.UxmlSerializedData.ShouldWriteAttributeValue(m_LocalizationKey_UxmlAttributeFlags))
                {
                    tab.LocalizationKey = m_LocalizationKey;
                }
                if (UnityEngine.UIElements.UxmlSerializedData.ShouldWriteAttributeValue(m_UseFrameworkLocalization_UxmlAttributeFlags))
                {
                    tab.UseFrameworkLocalization = m_UseFrameworkLocalization;
                }
#else
                tab.LocalizationKey = m_LocalizationKey;
                tab.UseFrameworkLocalization = m_UseFrameworkLocalization;
#endif
            }

#if UNITY_6000_0_OR_NEWER
            [Conditional("UNITY_EDITOR")]
            public new static void Register()
            {
                UxmlDescriptionCache.RegisterType(typeof(UxmlSerializedData), new UxmlAttributeNames[2]
                {
                    new UxmlAttributeNames("m_LocalizationKey", "localization-key", null),
                    new UxmlAttributeNames("m_UseFrameworkLocalization", "use-framework-localization", null)
                });
            }
#endif
        }

#if !UNITY_6000_0_OR_NEWER

        public new class UxmlFactory : UxmlFactory<LOTab, UxmlTraits>
        {

        }

        public new class UxmlTraits : Tab.UxmlTraits
        {
            private UxmlStringAttributeDescription m_LocalizationKey = new UxmlStringAttributeDescription
            {
                name = "localization-key",
                defaultValue = string.Empty
            };

            private UxmlBoolAttributeDescription m_UseFrameworkLocalization = new UxmlBoolAttributeDescription()
            {
                name = "use-framework-localization",
                defaultValue = true
            };

            public UxmlTraits() : base()
            {

            }

            public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
            {
                base.Init(ve, bag, cc);
                LOTab tab = (LOTab)ve;
                tab.LocalizationKey = m_LocalizationKey.GetValueFromBag(bag, cc);
                tab.UseFrameworkLocalization = m_UseFrameworkLocalization.GetValueFromBag(bag, cc);
            }
        }

#endif
        internal static readonly BindingId localizationKeyProperty = "localizationKey";
        internal static readonly BindingId useFrameworkLocalizationProperty = "useFrameworkLocalization";

        private string m_LocalizationKey;
        private bool m_UseFrameworkLocalization = true;

        internal Func<string, string> m_GetLocalizationContentEvent;

        [CreateProperty]
        public string LocalizationKey
        {
            get
            {
                return m_LocalizationKey ?? string.Empty;
            }

            set
            {
                if (m_LocalizationKey == value)
                {
                    return;
                }

                if (this.label == m_LocalizationKey)
                {
                    label = value;
                }
                m_LocalizationKey = value;

                ReplayLocalization();
                NotifyPropertyChanged(in localizationKeyProperty);
            }
        }

        [CreateProperty]
        public bool UseFrameworkLocalization
        {
            get
            {
                return m_UseFrameworkLocalization;
            }

            set
            {
                if (m_UseFrameworkLocalization == value)
                    return;

                m_UseFrameworkLocalization = value;
                NotifyPropertyChanged(in useFrameworkLocalizationProperty);
            }
        }

        public Func<string, string> GetLocalizationContentEvent
        {
            set
            {
                m_GetLocalizationContentEvent = value;
            }

            get
            {
                return m_GetLocalizationContentEvent;
            }
        }

        public void ReplayLocalization()
        {
            if (string.IsNullOrEmpty(m_LocalizationKey))
                return;

            if (m_UseFrameworkLocalization)
            {
                if (!LSEntry.Avalible)
                    return;

                var localzation = LSEntry.Localization;
                if (localzation == null)
                    return;

                string text = localzation.GetString(m_LocalizationKey);

                if (!string.IsNullOrEmpty(text))
                    this.label = text;
            }
            else
            {
                string text = m_GetLocalizationContentEvent?.Invoke(m_LocalizationKey);

                if (!string.IsNullOrEmpty(text))
                    this.label = text;
            }
        }

        void ILocalizationReplay.ReplayLocalization()
        {
            if (string.IsNullOrEmpty(m_LocalizationKey))
                return;

            if (m_UseFrameworkLocalization)
            {
                if (!LSEntry.Avalible)
                    return;

                var localzation = LSEntry.Localization;
                if (localzation == null)
                    return;

                string text = localzation.GetString(m_LocalizationKey);

                if (!string.IsNullOrEmpty(text))
                    this.label = text;
            }
            else
            {
                string text = m_GetLocalizationContentEvent?.Invoke(m_LocalizationKey);

                if (!string.IsNullOrEmpty(text))
                    this.label = text;
            }
        }
    }
}
#endif